<template>
  <el-container class="advance-query-form advance-box flow-entry-card-list">
    <el-aside width="300px">
      <el-card
        class="base-card"
        shadow="never"
        :body-style="{ padding: '0px' }"
        style="border: none; padding: 16px 0px"
      >
        <el-scrollbar :style="{ height: mainContextHeight - 64 + 'px' }">
          <el-tree
            ref="categoryIdTree"
            :data="categoryIdList"
            :props="{ label: 'name' }"
            node-key="id"
            :highlight-current="true"
            :current-node-key="(currentCategory || {}).id"
            @node-click="onCategoryChange"
          />
        </el-scrollbar>
      </el-card>
    </el-aside>
    <el-main style="margin-left: 15px; display: flex; flex-direction: column">
      <el-form
        ref="formFlowEntry"
        :model="formFilter"
        label-width="80px"
        :size="defaultFormItemSize"
        label-position="right"
        @submit.prevent
      >
        <filter-box :item-width="350" @search="refreshFormFlowEntry()" @reset="onReset">
          <el-form-item label="流程名称">
            <el-input
              class="filter-item"
              v-model="formFilter.processDefinitionName"
              :clearable="true"
              placeholder="流程名称"
            />
          </el-form-item>
        </filter-box>
      </el-form>
      <div style="flex: 1; background: white; border-radius: 4px; padding: 16px 24px">
        <el-scrollbar :style="{ height: '100%' }">
          <div class="card-list">
            <el-card
              v-for="(item, index) in filteredFlowEntryList"
              :key="index"
              class="base-card card-item"
              :body-style="{ padding: '0px', 'border-radius': '10px' }"
              shadow="hover"
              @click="onStartFlowEntryClick(item)"
            >
              <div class="card-content">
                <el-image :src="getImageUrl(item)" class="card-image" />
                <span style="margin-left: 16px; color: #7f8082">
                  {{ item.processDefinitionName }}
                </span>
              </div>
            </el-card>
          </div>
        </el-scrollbar>
      </div>
    </el-main>
    <el-dialog
      title="启动自动化任务"
      v-if="currentAutoTask"
      :visible="true"
      @close="currentAutoTask = undefined"
    >
      <el-row>
        <el-col :span="24">
          <el-table :data="currentAutoTask.autoParamJson" height="300px">
            <el-table-column prop="variableName" label="参数名" width="200px" />
            <el-table-column prop="variableValue" label="参数值">
              <template v-slot="scope">
                <el-input size="mini" v-model="scope.row.variableValue" clearable />
              </template>
            </el-table-column>
          </el-table>
        </el-col>
        <el-col :span="24" style="margin-top: 15px">
          <el-row type="flex" justify="end">
            <el-button size="small" type="primary" @click="startAutoTask(currentAutoTask)">
              启动
            </el-button>
          </el-row>
        </el-col>
      </el-row>
    </el-dialog>
  </el-container>
</template>

<script setup lang="ts">
import { ElMessage } from 'element-plus';
import { useRoute, useRouter } from 'vue-router';
import { useCommon } from '@/common/hooks/useCommon';
import { useUpload } from '@/common/hooks/useUpload';
import { useLayoutStore } from '@/store';
import { DropdownOptions, ListData } from '@/common/types/list';
import { TableOptions } from '@/common/types/pagination';
import { ANY_OBJECT } from '@/types/generic';
import { DictData } from '@/common/staticDict/types';
import defaultFlowIcon from '@/assets/img/defaultFlowIcon.png';
import { FlowEntryController, FlowDictionaryController, FlowOperationController } from '@/api/flow';
import {
  FlowEntryType,
  AutoTaskActionType,
  SysFlowTaskType,
  SysFlowTaskOperationType,
} from '@/common/staticDict/flow';

const layoutStore = useLayoutStore();
const { Plus, useDropdown, useTable, Dialog, mainContextHeight } = useCommon();
const { getUploadFileUrl, getUploadHeaders, getUploadActionUrl } = useUpload();
const router = useRouter();

const formFilter = ref({
  categoryId: undefined,
  processDefinitionName: undefined,
});
const formFilterCopy = ref({
  categoryId: undefined,
  processDefinitionName: undefined,
});
const categoryIdList = ref<DictData[]>([]);
const currentAutoTask = ref<ANY_OBJECT | undefined>(undefined);
const currentCategory = ref<DictData | undefined>(undefined);
const categoryIdTree = ref();

const filteredFlowEntryList = computed(() => {
  return flowEntryWidget.dataList.filter(item => {
    let find = true;
    // 流程名称是否匹配
    if (
      formFilterCopy.value.processDefinitionName != null &&
      formFilterCopy.value.processDefinitionName !== ''
    ) {
      find = item.processDefinitionName.indexOf(formFilterCopy.value.processDefinitionName) !== -1;
    }
    // 流程分类是否匹配
    if (
      formFilterCopy.value.categoryId != null &&
      formFilterCopy.value.categoryId !== '' &&
      formFilterCopy.value.categoryId !== 'all'
    ) {
      find = find && item.categoryId === formFilterCopy.value.categoryId;
    }

    return find;
  });
});

const loadFlowEntryWidgetData = (params: ANY_OBJECT) => {
  if (params == null) params = {};
  params = {
    ...params,
    flowEntryDtoFilter: {},
  };
  return new Promise((resolve, reject) => {
    FlowEntryController.listAllByStartFlow(params)
      .then(res => {
        res.data.forEach(item => {
          try {
            item.autoParamJson = JSON.parse(item.autoParamJson || '[]');
          } catch (e) {
            console.error('JSON parse error', e);
            item.autoParamJson = [];
          }
          item.autoParamJson = item.autoParamJson.map(param => {
            return {
              variableName: param.variableName,
              variableValue: param.variableValue,
            };
          });
        });
        resolve({
          dataList: res.data,
          totalCount: res.data.totalCount,
        });
      })
      .catch(e => {
        console.log(e);
        reject(e);
      });
  });
};
/**
 * FlowEntry数据获取检测函数，返回true正常获取数据，返回false停止获取数据
 */
const loadFlowEntryVerify = () => {
  return true;
};

const tableOptions: TableOptions<ANY_OBJECT> = {
  loadTableData: loadFlowEntryWidgetData,
  verifyTableParameter: loadFlowEntryVerify,
  paged: true,
  orderFieldName: 'entryId',
  ascending: true,
};

const flowEntryWidget = reactive(useTable(tableOptions));

const refreshFormFlowEntry = () => {
  formFilterCopy.value = {
    ...formFilter.value,
  };
};

const onReset = () => {
  formFilter.value.processDefinitionName = undefined;
  refreshFormFlowEntry();
};

const getImageUrl = item => {
  let imageData = item.imageData;
  if (imageData == null || imageData === '') {
    return defaultFlowIcon;
  }
  if (typeof imageData === 'string') {
    imageData = JSON.parse(imageData);
  }
  return getUploadFileUrl(imageData, {
    filename: imageData.filename,
  });
};

const loadCategoryList = () => {
  let params = {};
  FlowDictionaryController.dictFlowCategory(params)
    .then(res => {
      categoryIdList.value = res.getList();
      categoryIdList.value.unshift({
        id: 'all',
        name: '全部',
      });
      currentCategory.value = categoryIdList.value[0];
      nextTick(() => {
        if (categoryIdTree.value) categoryIdTree.value.setCurrentKey(currentCategory.value.id);
      });
    })
    .catch(e => {
      console.error(e);
    });
};

const onCategoryChange = data => {
  currentCategory.value = data;
  formFilter.value.categoryId = data.id;
  formFilterCopy.value.categoryId = data.id;
};

const onStartFlowEntryClick = row => {
  if (row.flowType === FlowEntryType.AUTO_TASK) {
    currentAutoTask.value = row;
    currentAutoTask.value.autoParamJson.forEach(item => {
      item.variableValue = '';
    });
  } else {
    currentAutoTask.value = null;
    startFlowTask(row);
  }
};

const startAutoTask = row => {
  let params = {
    processDefinitionKey: row.processDefinitionKey,
    variableData: row.autoParamJson.reduce((retObj, item) => {
      if (item.variableValue != null && item.variableValue !== '') {
        retObj[item.variableName] = item.variableValue;
      }
      return retObj;
    }, {}),
  };
  FlowOperationController.startAuto(params)
    .then(res => {
      ElMessage.success('启动成功！');
      currentAutoTask.value = null;
    })
    .catch(e => {
      ElMessage.error('启动失败！');
      currentAutoTask.value = null;
    });
};

const startFlowTask = row => {
  let params = {
    processDefinitionKey: row.processDefinitionKey,
  };
  FlowOperationController.viewInitialTaskInfo(params)
    .then(res => {
      if (res.data && res.data.taskType === SysFlowTaskType.USER_TASK && res.data.assignedMe) {
        let params = {
          processDefinitionKey: row.processDefinitionKey,
          formId: res.data.formId,
          routerName: res.data.routerName,
          readOnly: res.data.readOnly,
          taskName: '启动流程',
          taskKey: res.data.taskKey,
          flowEntryName: row.processDefinitionName,
          operationList: JSON.stringify(
            (res.data.operationList || []).filter(item => {
              return (
                item.type !== SysFlowTaskOperationType.CO_SIGN &&
                item.type !== SysFlowTaskOperationType.REVOKE &&
                item.type !== SysFlowTaskOperationType.SIGN_REDUCTION
              );
            }),
          ),
          isDraft: 'true',
          isPreview: 'true',
          variableList: JSON.stringify(res.data.variableList),
        };
        router.push({
          name: res.data.routerName || 'handlerFlowTask',
          query: params,
        });
      } else {
        FlowOperationController.startOnly({
          processDefinitionKey: row.processDefinitionKey,
        })
          .then(res => {
            ElMessage.success('启动成功！');
          })
          .catch(e => {
            // 启动失败
          });
      }
    })
    .catch(e => {
      // 获取流程信息失败
    });
};

onMounted(() => {
  loadCategoryList();
  flowEntryWidget.refreshTable();
});

onActivated(() => {
  flowEntryWidget.refreshTable();
});
</script>

<style scoped>
.flow-entry-card-list ::v-deep .el-tree-node__content {
  height: 35px;
}

.card-list {
  display: flex;
  flex-wrap: wrap;
}

.card-list .card-item {
  margin-right: 16px;
  margin-bottom: 16px;
  width: 300px;
  padding: 24px;
  border-radius: 8px;
  cursor: pointer;
}

.card-content {
  display: flex;
  align-items: center;
}

.card-image {
  width: 64px;
  height: 64px;
  flex-shrink: 0;
  flex-grow: 0;
}
</style>
